package com.xinruke.hostels.support.service.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.xinruke.hostels.central.manage.interfaces.api.CentralManageAPI;
import com.xinruke.hostels.central.manage.interfaces.dto.HotelAllQueryDTO;
import com.xinruke.hostels.common.po.YwJiudian;
import com.xinruke.hostels.common.vo.ResultVO;
import com.xinruke.hostels.support.generator.po.SysDiqu;
import com.xinruke.hostels.support.interfaces.dto.RegionQueryDto;
import com.xinruke.hostels.support.interfaces.dto.RegionQueryResultDto;
import com.xinruke.hostels.support.mapper.SysDiquMapper;
import com.xinruke.hostels.support.service.RegionService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.util.Sqls;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author GuoZheng
 * @ClassName RegionServiceImpl
 * @date：2019/6/13
 * @version: V1.0.0
 * @description：
 */
@Service
public class RegionServiceImpl implements RegionService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    private SysDiquMapper sysDiquMapper;

    @Resource
    private CentralManageAPI centralManageAPI;

    @Override
    public ResultVO<List<RegionQueryResultDto>> regionList(RegionQueryDto params) {
        ResultVO<List<RegionQueryResultDto>> resultVO = ResultVO.fail();
        //获取拥有酒店的去重后的所有省市县的集合
        List<String> ownRegionCode = getOwnRegionCodeList();
        //获取所有地区
        List<SysDiqu> allRegion = sysDiquMapper.selectByExample(Example
                .builder(SysDiqu.class).where(Sqls.custom()
                        .andBetween("cengji", SysDiqu.CENGJI_SHENGFEN, params.getCengji())
                ).build());
        List<SysDiqu> shengFenList = allRegion.stream().filter(r -> r.getCengji().equals(SysDiqu.CENGJI_SHENGFEN)).collect(Collectors.toList());
        //递归查询下级region
        List<RegionQueryResultDto> dataListResult = getAllSubRegion(shengFenList, allRegion,ownRegionCode);




        resultVO.setCode(ResultVO.SUCCESS);
        resultVO.setMessage("查询成功");
        resultVO.setData(dataListResult);
        return resultVO;
    }

    private List<String> getOwnRegionCodeList() {
        //查询所有酒店
        List<YwJiudian> allHotel = centralManageAPI.getAllHotel(new HotelAllQueryDTO());

        //拼接酒店的省，市，县
        List<String> regionList = allHotel.stream().map(h -> {
            List<String> regionCodes = Arrays.asList(h.getDishi(), h.getShengfen(), h.getXian());
            return StringUtils.join(regionCodes, ",");
        }).collect(Collectors.toList());
        //将省市县都转化字符串集合并去重
        return regionList.stream().flatMap(r-> Arrays.stream(r.split(","))).distinct().collect(Collectors.toList());
    }




    /**
     * 通过省份递归查询所有下级region
     * @param province
     * @param allRegion
     * @param ownRegionCode
     * @return
     */
    private List<RegionQueryResultDto> getAllSubRegion(List<SysDiqu> province, List<SysDiqu> allRegion, List<String> ownRegionCode) {
        List<RegionQueryResultDto> resultDtos = new ArrayList<>();
        province.forEach( p ->{
            RegionQueryResultDto parentRegionDto = new RegionQueryResultDto();
            BeanUtils.copyProperties(p,parentRegionDto);
            //标识地区是否酒店
            boolean own = ownRegionCode.stream().anyMatch(o -> parentRegionDto.getBianma().equals(o));
            if (own) {
                parentRegionDto.setFlag(RegionQueryResultDto.OWN);
            }

            List<SysDiqu> subRegionList = allRegion.stream().filter(r -> r.getShangjiBianma().equals(p.getBianma())).collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(subRegionList)){
                parentRegionDto.getSubRegionDtoList().addAll(getAllSubRegion(subRegionList, allRegion, ownRegionCode));
            }
            resultDtos.add(parentRegionDto);
        });
        return resultDtos;
    }

    public List<SysDiqu> getSysDiquList(SysDiqu vo) {
        long begin = System.currentTimeMillis();
        List<SysDiqu> areaStreetList = sysDiquMapper.getDataList(vo);
        long end = System.currentTimeMillis();
        logger.info("getSysDiquList size={} take times={}ms", areaStreetList.size(), (end - begin));
        return areaStreetList;
    }

    @Override
    public Map getSysDiquInfoByAreaName(SysDiqu sysDiqu) {
        long begin = System.currentTimeMillis();
        Map resultMap = Maps.newHashMap();
        List<SysDiqu> areaStreetList = sysDiquMapper.getDataList(sysDiqu);
        if (areaStreetList != null && areaStreetList.size() > 0) {
            SysDiqu currSysDiqu = areaStreetList.get(0);
            if (currSysDiqu.getCengji() == 3) {
                resultMap.put("code", currSysDiqu.getBianma());
                resultMap.put("name", currSysDiqu.getMingcheng());
            }
        }
        long end = System.currentTimeMillis();
        logger.info("getSysDiquInfoByAreaName take times={}ms", (end - begin));
        return resultMap;
    }

    @Override
    public List<Map> getSysDiquAllList() {
        long begin = System.currentTimeMillis();
        SysDiqu queryVo = new SysDiqu();
        queryVo.setCengji(1);
        queryVo.setShangjiBianma("0");
        List<SysDiqu> areaStreetList = sysDiquMapper.selectAllList(queryVo);
        List<Map> respList = Lists.newLinkedList();
        for (SysDiqu areaStreet1 : areaStreetList) {
            Map provinceMap = Maps.newHashMap();
            provinceMap.put("code", areaStreet1.getBianma());
            provinceMap.put("level", areaStreet1.getCengji());
            provinceMap.put("parentid", areaStreet1.getShangjiBianma());
            provinceMap.put("name", areaStreet1.getMingcheng());
            List<Map> cityList = Lists.newLinkedList();
            provinceMap.put("cityMap", cityList);
            respList.add(provinceMap);

            SysDiqu areaStreetCityVO = new SysDiqu();
            areaStreetCityVO.setCengji(2);
            areaStreetCityVO.setShangjiBianma(areaStreet1.getBianma());
            List<SysDiqu> areaStreetCityList = sysDiquMapper.selectAllList(areaStreetCityVO);
            for (SysDiqu areaStreetCity : areaStreetCityList) {
                Map cityMap = Maps.newHashMap();
                cityMap.put("code", areaStreetCity.getBianma());
                cityMap.put("level", areaStreetCity.getCengji());
                cityMap.put("parentid", areaStreetCity.getShangjiBianma());
                cityMap.put("name", areaStreetCity.getMingcheng());
                List<Map> countyList = Lists.newLinkedList();
                cityMap.put("countyMap", countyList);

                cityList.add(cityMap);

                SysDiqu areaStreetCountyVO = new SysDiqu();
                areaStreetCountyVO.setCengji(3);
                areaStreetCountyVO.setBianma(areaStreetCity.getBianma());
                List<SysDiqu> areaStreetCountyList = sysDiquMapper.selectAllList(areaStreetCountyVO);
                for (SysDiqu areaStreetCounty : areaStreetCountyList) {
                    Map countyMap = Maps.newHashMap();
                    countyMap.put("code", areaStreetCounty.getBianma());
                    countyMap.put("level", areaStreetCounty.getCengji());
                    countyMap.put("parentid", areaStreetCounty.getShangjiBianma());
                    countyMap.put("name", areaStreetCounty.getMingcheng());
                    countyList.add(countyMap);
                }
            }
        }
        long end = System.currentTimeMillis();
        logger.info("getSysDiquALLList size={} take times={}ms", respList.size(), (end - begin));
        return respList;
    }
}
